<?php
require_once ('utils' . DIRECTORY_SEPARATOR . 'HHAbstract.php');

set_time_limit(-1);

class HHSInvestmentMap extends HHAbstract {

	function __construct() {
		parent::__construct();
	}

	function __destruct() {
		parent::__destruct();
	}

	function constructClass() {

		$this -> handleARGV();
	}

	function handleARGV() {
		global $argv;
		if (!isset($argv) || count($argv) <= 1) {
			$isAjax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) AND strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
			if ($isAjax) {
				$this -> getXML();
			}
			else {
				if (isset($_REQUEST['isAjax']) && $_REQUEST['isAjax'] == true) {
					$this -> getXML();
				}
			}

		}
		else {
			array_shift($argv);
			foreach ($argv as $value) {
				$keyArray = split("=", $value);
				$key = $keyArray[0];
				$keyValue = $keyArray[1];
				switch ($key) {
					case "updateXML" :
						$this -> updateXML('bid');
						$this -> updateXML('prop');
						die(" XML files fully updated | Time: " . date("m-d-y h:i:s A") . "<br>");
						break;
					default :
						echo("Incorrect argument usage. Please use one of the following:\n");
					case "options" :
						$options = array(
							"options" => "Display the options list",
							"updateXML" => "Update the xml files used to populate the map with markers and hotspots"
						);
						$space = 0;
						foreach (array_keys ( $options ) as $opKey) {
							$space = (strlen($opKey) > $space) ? strlen($opKey) : $space;
						}
						$space += 5;
						$spaceString = '';
						for ($i = 0; $i < $space; $i++) {
							$spaceString .= " ";
						}
						$length = 70;
						foreach ($options as $opKey => $opValue) {
							$lineCount = 0;
							$displayArray = array();
							$displayArray[$lineCount] = ("\n$opKey" . substr($spaceString, strlen($opKey)));
							$opValueArray = explode(" ", $opValue);
							foreach ($opValueArray as $opValueWord) {
								if ((strlen($displayArray[$lineCount]) + strlen($opValueWord)) <= $length) {
									$displayArray[$lineCount] .= $opValueWord . " ";
								}
								else {
									$lineCount++;
									$displayArray[$lineCount] .= $spaceString . $opValueWord . " ";
								}
							}
							echo(implode("\n", $displayArray) . "\n");
						}
						break;
				}
			}
		}
	}

	function updateXML($type = 'bid') {
		$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tmp';
		$fileName = $path . DIRECTORY_SEPARATOR . $type . "Results.xml";
		// Start XML file, create parent node
		$dom = new DOMDocument();
		$node = $dom -> createElement("nodes");
		$parnode = $dom -> appendChild($node);

		$hudUrl = 'https://www.hudhomestore.com/Listing/BidResults.aspx?zipCode=&city=&county=&street=&sState=0&caseNumber=%s&pageId=1&OrderbyName=SCASENUMBER&OrderbyValue=ASC&sLanguage=ENGLISH';
		$query = 'Select `case`, address, city, state, zip, county, lat, lon, if(purchaser_type=\'INV\',\'INV\',\'OO\') as purchaser_type from bid_results';
		if ($type != 'bid') {
			$hudUrl = 'http://www.hudhomestore.com/Listing/PropertyDetails.aspx?caseNumber=%s';
			$query = 'Select `case`, address, city, state, zip, county, lat, lon, if(list_period=\'Extended\',\'INV\',\'OO\') as purchaser_type from property_list';
		}

		//WHERE purchaser_type="INV"';
		$results = $this -> getDBConnection() -> queryDB($query);
		// Iterate through the rows, adding XML nodes for each
		while (($row = $results -> fetch_assoc())) {

			// ADD TO XML DOCUMENT NODE
			$node = $dom -> createElement("marker");
			$newnode = $parnode -> appendChild($node);
			$href = sprintf($hudUrl, $row['case']);
			$newnode -> setAttribute("name", '<a href="' . $href . '">Case: ' . $row['case'] . '</a>');
			$newnode -> setAttribute("address", $row['address'] . '<br>' . $row['city'] . ', ' . $row['state'] . ' ' . $row['zip'] . '<br>' . $row['county']);
			$newnode -> setAttribute("lat", $row['lat']);
			$newnode -> setAttribute("lng", $row['lon']);
			$newnode -> setAttribute("type", $row['purchaser_type']);
		}

		$query = 'Select * from bid_result_clusters';
		if ($type == 'bid') {
			$results = $this -> getDBConnection() -> queryDB($query);
			// Iterate through the rows, adding XML nodes for each
			while (($row = $results -> fetch_assoc())) {

				// ADD TO XML DOCUMENT NODE
				$node = $dom -> createElement("circle");
				$newnode = $parnode -> appendChild($node);
				//$newnode -> setAttribute("radius", ($row['radius']*6371));
				$newnode -> setAttribute("radius", ($row['radius'] * 2000));

				// Find the center point of the given lats and lons
				$lats = explode(',', $row['lats']);
				$lons = explode(',', $row['lons']);
				$totalWeight = count($lats);

				$x = array();
				$y = array();
				$z = array();

				//Convert lat/long to cartesian (x,y,z) coordinates
				foreach ($lats as $index => $lat) {
					$lat = deg2rad($lat);
					$lon = deg2rad($lons[$index]);

					$x[] = cos($lat) * cos($lon);
					$y[] = cos($lat) * sin($lon);
					$z[] = sin($lat);
				}

				//Compute combined weighted cartesian coordinate
				$X = array_sum($x) / $totalWeight;
				$Y = array_sum($y) / $totalWeight;
				$Z = array_sum($z) / $totalWeight;

				//Convert cartesian coordinate to latitude and longitude for the midpoint
				$lon = atan2($Y, $X);
				$hyp = sqrt($X * $X + $Y * $Y);
				$lat = atan2($Z, $hyp);

				//Convert midpoint lat and lon from radians to degrees
				$lat = rad2deg($lat);
				$lon = rad2deg($lon);

				$newnode -> setAttribute("lat", $lat);
				//center lat
				$newnode -> setAttribute("lng", $lon);
				// center lon
				$newnode -> setAttribute("type", str_replace('/', '', $row['purchaser_type']));
				$newnode -> setAttribute("cluster_count", $row['cluster_count']);
			}
		}

		$output = $dom -> saveXML();
		file_put_contents($fileName, $output);
		return $output;
	}

	function getXML($type = 'bid') {
		if(isset($_REQUEST['type'])){
			$type = $_REQUEST['type'];
		}

		$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tmp';
		$fileName = $path . DIRECTORY_SEPARATOR . $type . "Results.xml";

		//Check the modification time of the bid xml file saved
		// If it is older than a day then update it
		if ((!file_exists($fileName)) || (date("d", filemtime($fileName)) != date("d"))) {
			$output = $this -> updateXML($type);
		}
		else {
			$output = file_get_contents($fileName);
		}
		ob_end_clean();
		header("Content-type: text/xml");
		die($output);
	}

}

$obj = new HHSInvestmentMap();
//$obj -> getXML();
?>
<!DOCTYPE html >
<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
	<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
	<title>Hud Homes Store Investor Map</title>
	<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
	<script type="text/javascript">
		//<![CDATA[

		var customIcons = {
			INV : {
				icon : 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
				shadow : 'http://labs.google.com/ridefinder/images/mm_20_shadow.png',
				color : '#0000FF'
			},
			OO : {
				icon : 'http://labs.google.com/ridefinder/images/mm_20_red.png',
				shadow : 'http://labs.google.com/ridefinder/images/mm_20_shadow.png',
				color : '#FF0000'
			}
		};

		var mapObjTypes = {
			INV : new Array(),
			OO : new Array(),
			CIRCLE : new Array(),
			MARKER : new Array(),
		};

		var typeToggle = {
			INV : false,
			OO : false,
			CIRCLE : false,
			MARKER : false,
		}

		function load() {
			var map = new google.maps.Map(document.getElementById("map"), {
				center : new google.maps.LatLng(47.6145, -122.3418),
				zoom : 4,
				mapTypeId : 'roadmap'
			});

			var geocoder = new google.maps.Geocoder();
			var location = "United States";
			geocoder.geocode({
				'address' : location
			}, function(results, status) {
				if (status == google.maps.GeocoderStatus.OK) {
					map.setCenter(results[0].geometry.location);
				} else {
					alert("Could not find location: " + location);
				}
			});
			var infoWindow = new google.maps.InfoWindow;

			// Change this depending on the name of your PHP file
			downloadUrl("HHSInvestmentMap.php?isAjax=1&type="+<?php
			if(isset($_REQUEST['type'])){
				echo '"'.$_REQUEST['type'].'"';
			}else{
				echo '"bid"';
			}
			?>, function(data) {

				var xml = data.responseXML;
				var markers = xml.documentElement.getElementsByTagName("marker");
				for (var i = 0; i < markers.length; i++) {
					var name = markers[i].getAttribute("name");
					var address = markers[i].getAttribute("address");
					var type = markers[i].getAttribute("type");
					var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
					var html = "<b>" + name + "</b> <br/>" + address;
					var icon = customIcons[type] || {};
					var marker = new google.maps.Marker({
						map : map,
						position : point,
						icon : icon.icon,
						shadow : icon.shadow
					});
					bindInfoWindow(marker, map, infoWindow, html);
					mapObjTypes[type].push(marker);
					mapObjTypes['MARKER'].push(marker);
				}

				var circles = xml.documentElement.getElementsByTagName("circle");
				for (var i = 0; i < circles.length; i++) {
					var type = circles[i].getAttribute("type");
					var radius = circles[i].getAttribute("radius");
					var cluster_count = circles[i].getAttribute("cluster_count");
					var center = new google.maps.LatLng(parseFloat(circles[i].getAttribute("lat")), parseFloat(circles[i].getAttribute("lng")));
					var html = "<b> Cluster of " + type + ": Count: " + cluster_count + "</b> <br/>" + address;
					var icon = customIcons[type] || {};

					// Construct the circle for each value in citymap. We scale population by 20.
					var populationOptions = {
						strokeColor : icon.color,
						strokeOpacity : Math.min((0.20) + (0.10 * (parseInt(cluster_count / 15))), 0.8),
						strokeWeight : 2,
						fillColor : icon.color,
						fillOpacity : Math.min((0.20) + (0.05 * (parseInt(cluster_count / 15))), 0.35),
						map : map,
						center : center,
						radius : parseFloat(radius)
					};
					var circle = new google.maps.Circle(populationOptions);
					bindInfoWindow(circle, map, infoWindow, html);
					if(type!='OO'&&type!='INV'&&type!='CIRCLE'&&type!='MARKER'){
						console.log('Type not found: '+type);
					}else{
						mapObjTypes[type].push(circle);
					}
					mapObjTypes['CIRCLE'].push(circle);
				}
			});
		}

		function bindInfoWindow(marker, map, infoWindow, html) {
			google.maps.event.addListener(marker, 'click', function() {
				infoWindow.setContent(html);
				infoWindow.open(map, marker);
			});
		}

		function downloadUrl(url, callback) {
			var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest;

			request.onreadystatechange = function() {
				if (request.readyState == 4) {
					request.onreadystatechange = doNothing;
					callback(request, request.status);
				}
			};

			request.open('GET', url, true);
			request.send(null);
		}

		function doNothing() {
		}

		function toggleObj(type) {
			for (var i = 0; i < mapObjTypes[type].length; i++) {
				var obj = mapObjTypes[type][i];
				obj.setVisible(typeToggle[type]);
			}
			typeToggle[type] = !typeToggle[type];
		}

		//]]>

	</script>

</head>

<body onload="load()">
	<div id="map" style="width: 800px; height: 600px;"></div>
	<input type="button" value="Toggle Investors" onClick="toggleObj('INV')"}>
	<input type="button" value="Toggle Owner Occupied" onClick="toggleObj('OO')"}>
	<input type="button" value="Toggle Markers" onClick="toggleObj('MARKER')"}>
	<input type="button" value="Toggle Hot Spots" onClick="toggleObj('CIRCLE')"}>
</body>

</html>
